/**
 * @Author: Bobby
 * @Date: 2022-02-15 13:14:17
 * @LastEditTime: 2022-03-22 16:47:29
 * @LastEditors: Bobby
 * @Description:
 * @FilePath: \wms-v2\src\ve\mixin\elementsFormMixin.js
 * @CIMC-V2
 */
import isEmpty from 'lodash/isEmpty'
import isArray from 'lodash/isArray'
import isPlainObject from 'lodash/isPlainObject'
import cloneDeep from 'lodash/cloneDeep'
import isFinite from 'lodash/isFinite'
import trim from 'lodash/trim'
import keys from 'lodash/keys'
import set from 'lodash/set'
import unset from 'lodash/unset'
import dayjs from 'dayjs'

import { setModels, getComponentDefaulType, processingConstant, getModelByModelTree, getCascaderShow } from '@ve/utils/utils'
import { defineAsyncComponent } from 'vue'

//表单
export default {
  components: {
    UiFormItem: defineAsyncComponent(() => import('@ve/components/uiFormItem.vue')),
    UiPdaFormItem: defineAsyncComponent(() => import('@ve/components/uiPdaFormItem.vue')),
  },
  inject: {
    formId: { default: '' },
  },
  props: {
    info: {
      required: true,
      type: Object,
      default: function () {
        return {}
      },
    },
  },
  data() {
    return {
      selfData: {}, //没有formData时候绑定到这里
      getLocationPageId: '', // 当前组件的所属页面ID
      // __form: {},
    }
  },
  watch: {
    info: {
      deep: true,
      handler() {
        if (!this.getHasPreview) {
          //开发模式下调用 用于更新input name
          setModels(this.$store.getters['diy/getPageModules'])
        }
      },
    },
    // formDataModel: {
    //   handler() {
    //     // console.log('watch-------newVal', newVal)
    //     // 触发条件判断模块组件值改变
    //     // this.setPageModulesState && this.setPageModulesState('value', newVal)
    //     // 触发组件的值改变事件
    //     this.onChange()
    //   },
    // },
    optionConfig: {
      deep: true,
      handler(newval) {
        if (!newval) return
        console.log(newval, 'newval', this.formDataModel)
        const mode = process.env.VUE_APP_BuildProjectType === 'mobile' || this.$store.state.diy.settings.mode == 'mobile'
        if (mode) {
          if (!isEmpty(newval.value) && !isEmpty(this.formDataModel)) {
            let chaceItem = newval.value.find((v) => {
              return v[this.info.extension.valueField.value] == this.formDataModel
            })
            if (isEmpty(chaceItem)) {
              return
            }
            this.formDataModelLabel = processingConstant(this, chaceItem[this.info.extension.labelField.value])
          }
        }
      },
    },
  },
  computed: {
    getHasPreview() {
      return this.$store.getters['preview/getHasPreview']
    },
    formDataModel: {
      get() {
        let _model = cloneDeep(this.getFormData(false, this.info.extension.model.value))
        _model = _model === undefined ? getComponentDefaulType(this.info.type) : _model
        if (isPlainObject(_model) && (this.info.type === 'uiDate' || this.info.type === 'uiTimePicker')) {
          // 如果值类型为处理过后的 object 则需要转为数组类型
          const startSuffix = this.info.extension?.startSuffix?.value ? this.info.extension?.startSuffix?.value : '_start'
          const endSuffix = this.info.extension?.endSuffix?.value ? this.info.extension?.endSuffix?.value : '_end'
          _model = [_model[`${this.info.extension.model.value}${startSuffix}`], _model[`${this.info.extension.model.value}${endSuffix}`]]
        } else if (this.info.type.indexOf('uiSelect') !== -1 && this.info.extension?.multiple?.value) {
          // 如果组件为下拉选择 并且为多选状态 则需要将值转换为数组类型
          _model = _model && _model.split(',')
        } else if (this.info.type === 'uiCheckbox' || this.info.type === 'uiTransfer') {
          // 如果组件为多选框或者穿梭框 则需要将值转换为数组类型
          if (_model) {
            _model = _model.split(',')
          } else {
            _model = []
          }
        } else if (this.info.type === 'uiNumberInput') {
          // 如果组件为数值输入框 则需要判断值类型
          _model = isFinite(_model) ? _model : 0
        } else if (this.info.type === 'uiCascader') {
          // 如果组件为数值输入框 则需要判断值类型
          console.log('uiCascader', cloneDeep(_model), this.info.extension)
          if (this.info.extension?.model?.value === 'REPORT_ID') {
            if (_model) {
              _model = _model.split(',')
            } else {
              _model = []
            }
          } else if (this.info.extension?.multipleLast?.value) {
            if (this.vuiComponents[this.info._id] && this.vuiComponents[this.info._id]?.self?.optionList) {
              _model = getCascaderShow(this.vuiComponents[this.info._id]?.self?.optionList, _model, 'children', 'ID', 'PARENT_ID')
            }
          } else {
            let list = []
            if (isArray(_model) && _model.length > 0) {
              _model.forEach((row) => {
                list.push([row[this.info.extension?.subKey?.value], row[this.info.extension?.subleveSsubKey?.value]])
              })
              _model = list
            }
          }
        }
        return _model
      },
      set(value) {
        let _model = this.getFormData(true)
        // 如果组件为时间选择器 且数据为数组类型 则将数据做进一步处理
        if ((this.info.type === 'uiDate' || this.info.type === 'uiTimePicker') && isArray(value)) {
          let dataObj = {}
          const startSuffix = this.info.extension?.startSuffix?.value ? this.info.extension?.startSuffix?.value : '_start'
          const endSuffix = this.info.extension?.endSuffix?.value ? this.info.extension?.endSuffix?.value : '_end'
          dataObj[`${this.info.extension.model.value}${startSuffix}`] = value[0] || ''
          dataObj[`${this.info.extension.model.value}${endSuffix}`] = value[1] || ''
          // 覆盖原有 value 值
          value = dataObj
          // 如果如果组件为时间选择器 且数据为时间区间，则需要将值提取到外层，方便后端取值
          keys(value).forEach((KeyItem) => {
            _model[KeyItem] = value[KeyItem]
          })
        } else if (
          (this.info.type === 'uiDate' && this.info.extension?.selection?.value === 'datetimerange') ||
          (this.info.extension?.selection?.value === 'daterange' && !value)
        ) {
          // 如果时间组件类型为时间范围 则清空之前缓存的值
          const startSuffix = this.info.extension?.startSuffix?.value ? this.info.extension?.startSuffix?.value : '_start'
          const endSuffix = this.info.extension?.endSuffix?.value ? this.info.extension?.endSuffix?.value : '_end'
          _model[`${this.info.extension.model.value}${startSuffix}`] = ''
          _model[`${this.info.extension.model.value}${endSuffix}`] = ''
        } else if (this.info.type.indexOf('uiSelect') !== -1 && this.info.extension?.multiple?.value) {
          // 如果组件为下拉选择 并且为多选状态 则需要将值转换为数组类型
          value = isArray(value) ? value.join(',') : value
        } else if (this.info.type === 'uiCheckbox' || this.info.type === 'uiTransfer') {
          // 如果组件为多选框或者穿梭框 则需要将值转换为数组类型
          value = isArray(value) ? value.join(',') : value
        } else if (this.info.type === 'uiNumberInput') {
          // 如果组件为数值输入框 则需要判断值类型
          value = isFinite(value) ? value : 0
        } else if (this.info.type === 'uiCascader') {
          // 如果组件为级联 则需要判断值类型
          if (this.info.extension?.lastLevel?.value || this.info.extension?.checkStrictly?.value) {
            value = value ? value[value.length - 1] : ''
          } else {
            console.log('uiCascader', cloneDeep(value))
            // value = list
            // 这里时打印模板
            if (this.info.extension?.model?.value === 'REPORT_ID') {
              value = isArray(value) ? value.join(',') : value
            } else if (this.info.extension?.multipleLast?.value) {
              let list = []
              value.forEach((row) => {
                list.push(row[row.length - 1])
              })
              value = isArray(list) ? list.join(',') : list
            } else if (isArray(value)) {
              let list = []
              value.forEach((row) => {
                if (isArray(row) && row.length > 0) {
                  let obj = {}
                  obj[this.info.extension?.subKey?.value] = row[0]
                  obj[this.info.extension?.subleveSsubKey?.value] = row[1]
                  list.push(obj)
                } else {
                  list.push(row)
                }
              })
              value = list
            }
          }
        }
        if (value === null) value = ''
        _model[this.info.extension?.model?.value] = value
      },
    },
    optionConfig() {
      return this.info.extension.optionConfig
    },
    // getLocationPageId() {
    //   return this.$store.getters['preview/getNowPageId']
    // },
  },

  created() {
    this.getLocationPageId = this.$store.getters['preview/getNowPageId']
  },

  mounted() {
    if (!this.getHasPreview) {
      return
    }
    if (this.info.extension.defaultValue && this.info.extension.defaultValue.value) {
      this.formDataModel = processingConstant(this, this.info.extension.defaultValue.value)
      // Eva操作vant的下拉选
      if (this.info.type == 'uiPdaSelect') {
        if (!isEmpty(this.info.extension.optionConfig.value)) {
          let chaceItem = this.info.extension.optionConfig.value.find((v) => {
            return v[this.info.extension.valueField.value] == this.formDataModel
          })
          if (isEmpty(chaceItem)) {
            return
          }
          this.formDataModelLabel = processingConstant(this, chaceItem[this.info.extension.labelField.value])
        }
      }
    }
  },
  methods: {
    //常量处理
    processingConstant() {
      let _defValue = trim(this.info.extension.defaultValue.value)
      let _getConstant = this.$store.getters['user/getConstant']
      let _value = ''
      switch (_defValue) {
        case '#USER_ID#':
          _value = this.$store.getters['user/uid']
          break
        case '#TOKEN#':
          _value = this.$store.getters['user/token']
          break
        case '#USER_NAME#':
          _value = this.$store.getters['user/username']
          break
        case '#ORG_ID#':
          _value = _getConstant['#ORG_ID#']
          break
        case '#APP_ID#':
          _value = this.$store.getters['user/appId']
          break
        case '#APP_CODE#':
          _value = this.$store.getters['user/appCode']
          break
        case '#WH_ID#':
          _value = _getConstant['#WH_ID#']
          break
        case '#LANGUAGE_CODE#':
          _value = this.$store.getters['user/language']
          break
        case '#AUTH_WH_ID#':
          _value = _getConstant['#AUTH_WH_ID#']
          break
        case '#AUTH_OWNER_ID#':
          _value = _getConstant['#AUTH_OWNER_ID#']
          break
        case '#AUTH_ORG_ID#':
          _value = _getConstant['#AUTH_ORG_ID#']
          break
        case '#AUTH_ORDER_RCV#':
          _value = _getConstant['#AUTH_ORDER_RCV#']
          break
        case '#AUTH_ORDER_SO#':
          _value = _getConstant['#AUTH_ORDER_SO#']
          break
        case '#AUTH_ORDER_CC#':
          _value = _getConstant['#AUTH_ORDER_CC#']
          break
        case '#AUTH_ORDER_ADJ#':
          _value = _getConstant['#AUTH_ORDER_ADJ#']
          break
        case '#AUTH_ORDER_MOV#':
          _value = _getConstant['#AUTH_ORDER_MOV#']
          break
        case '#AUTH_ORDER_TSF#':
          _value = _getConstant['#AUTH_ORDER_TSF#']
          break
        case '#AUTH_ORDER_FRZ#':
          _value = _getConstant['#AUTH_ORDER_FRZ#']
          break
        case '#CURRENT_DATE#':
          _value = dayjs().format('YYYY-MM-DD')
          break
        case '#CURRENT_DATETIME#':
          _value = dayjs().format('YYYY-MM-DD HH:mm:ss')
          break
        default:
          _value = _defValue
          break
      }
      return _value
    },
    getFormData(getAll, key = '') {
      if (isEmpty(this.formId)) {
        return getAll ? this.selfData : this.selfData[key]
      } else {
        if (this.hasPreview) {
          let _from = this.$store.getters['preview/getDeepModelOrLayerInfoByCurrentPage']({
            type: 1,
            id: this.formId,
            dataKey: '',
            pageId: this.getLocationPageId,
          })
          let formData = isEmpty(_from) ? this.selfData : _from.data.formData
          // let formData = isEmpty(this.__from) ? this.selfData : this.__from.data.formData
          return getAll ? formData : formData[key]
        } else {
          let formData = this.selfData
          return getAll ? formData : formData[key]
        }
      }
    },
    setFormDataModel(value) {
      this.formDataModel = value
    },
    $openFormItemRule() {
      // console.log('开启组件验证 ------  ', this)
      // 先查找对应的form组件
      const formModel =
        this.$store.state.preview?.pagesMods[this.getLocationPageId] && this.$store.state.preview?.pagesMods[this.getLocationPageId][this.formId]
      // console.log('formModel', formModel)
      if (formModel && formModel._rules && formModel._rules[this.info.extension.model.value]) {
        // 如果有对应的form组件并且有验证规则缓存，则替换添加验证规则
        formModel.rules[this.info.extension.model.value] = formModel._rules[this.info.extension.model.value]
        unset(formModel._rules, this.info.extension.model.value)
      }
    },
    $closeFormItemRule() {
      // console.log('关闭组件验证 ------  ')
      // 先查找对应的form组件
      const formModel =
        this.$store.state.preview?.pagesMods[this.getLocationPageId] && this.$store.state.preview?.pagesMods[this.getLocationPageId][this.formId]
      // console.log('formModel', formModel)
      if (formModel) {
        // 如果有对应的form组件，则删除所选的验证规则并且缓存验证规则
        formModel._rules = formModel._rules || {}
        // 如果当前组件已经禁用则不替换，防止多次禁用组件验证导致验证无法开启
        if (!formModel._rules[this.info.extension.model.value] && formModel.rules[this.info.extension.model.value]) {
          set(formModel._rules, this.info.extension.model.value, formModel.rules[this.info.extension.model.value])
          unset(formModel.rules, this.info.extension.model.value)
        }
      }
    },
    $handleEnter() {
      // 回车事件
      console.log('点击了回车！！！', this)
      // 使当前组件失焦
      let currentModuleRef = this.vuiComponents[this.info._id] && this.vuiComponents[this.info._id].ref
      currentModuleRef && currentModuleRef.blur && currentModuleRef.blur()
      // 触发回车事件
      this.defaultFocusNextModule = false
      this.onEnterKeyUp &&
        this.onEnterKeyUp((_this) => {
          // 将回车选中下一个组件放在回车事件之后 以方便控制动作中接口报错不聚焦下一个组件
          // 如果有配置回车选中 则选中组件
          let selectedModuleId = _this.info.extension.enterSelect && _this.info.extension.enterSelect.value[0]
          if (_this.info._id.indexOf('UiDynamicFormLOT') > -1) {
            // 如果当前事件是由批次属性内部组件触发则聚焦到下一个组件
            const currentIndex = _this.info.CUR_LOT_list.indexOf(_this.info._id)
            if (currentIndex === -1) return
            if (currentIndex < _this.info.CUR_LOT_list.length - 1) {
              // 如果当前组件已经是批次属性组件内的最后一个可聚焦组件 则聚焦到配置的外部组件
              selectedModuleId = _this.info.CUR_LOT_list[currentIndex + 1]
            } else {
              // 如果当前是批次属性里面的最后一个组件触发的回车点击 则触发批次属性组件的回车事件
              const parentId = _this.info.parentId
              this.dynamicFormEnterKeyUp(parentId)
              return
            }
          } else if (selectedModuleId && selectedModuleId.indexOf('uiDynamicFormLot') > -1) {
            // 如果选择的是批次属性组件 则进入批次属性组件内部
            const moduleTree = _this.$store.state.preview.pages[_this.$store.state.preview.nowPageId]
            const lotModule = getModelByModelTree(selectedModuleId, moduleTree)
            if (lotModule.CUR_LOT_list && lotModule.CUR_LOT_list.length) {
              // 如果批次属性组件有配置光标停留组件，则聚焦第一个组件
              selectedModuleId = lotModule.CUR_LOT_list[0]
            }
          }
          if (!selectedModuleId) return
          if (selectedModuleId.indexOf('uiSelectLayerNew') > -1 || selectedModuleId.indexOf('uiButton') > -1) {
            // 如果下一个组件是三点选择组件 或者按钮组件 则单独触发组件的回车选中方法
            const moduleSelf = _this.vuiComponents[selectedModuleId] && _this.vuiComponents[selectedModuleId].self
            moduleSelf && moduleSelf.enterFocus()
          } else {
            const moduleRef = _this.vuiComponents[selectedModuleId] && _this.vuiComponents[selectedModuleId].ref
            if (moduleRef && moduleRef.focus) {
              moduleRef.focus()
            }
            if (moduleRef && moduleRef.select) {
              moduleRef.select()
            }
            if (_this.info.type === 'uiSelect') {
              // 如果是下拉选择组件 则使下拉组件失去焦点 并隐藏选择框
              const selfModuleRef = _this.vuiComponents[_this.info._id] && _this.vuiComponents[_this.info._id].ref
              selfModuleRef.blur()
            }
          }
        })
    },
    // 批次属性回车事件
    dynamicFormEnterKeyUp(parentId) {
      console.log('parentId ============== ', parentId, this)
      if (!parentId) return
      const parentModuleSelf = this.vuiComponents[parentId] && this.vuiComponents[parentId].self
      parentModuleSelf.onEnterKeyUp &&
        parentModuleSelf.onEnterKeyUp((_this) => {
          let selectedModuleId = _this.info.extension.enterSelect && _this.info.extension.enterSelect.value[0]
          if (selectedModuleId && selectedModuleId.indexOf('uiDynamicFormLot') > -1) {
            // 如果选择的是批次属性组件 则进入批次属性组件内部
            const moduleTree = _this.$store.state.preview.pages[_this.$store.state.preview.nowPageId]
            const lotModule = getModelByModelTree(selectedModuleId, moduleTree)
            if (lotModule.CUR_LOT_list && lotModule.CUR_LOT_list.length) {
              // 如果批次属性组件有配置光标停留组件，则聚焦第一个组件
              selectedModuleId = lotModule.CUR_LOT_list[0]
            }
          }
          if (!selectedModuleId) return
          if (selectedModuleId.indexOf('uiSelectLayerNew') > -1 || selectedModuleId.indexOf('uiButton') > -1) {
            // 如果下一个组件是三点选择组件 则单独触发组件的回车选中方法
            const moduleSelf = _this.vuiComponents[selectedModuleId] && _this.vuiComponents[selectedModuleId].self
            moduleSelf && moduleSelf.enterFocus()
          } else {
            const moduleRef = _this.vuiComponents[selectedModuleId] && _this.vuiComponents[selectedModuleId].ref
            if (moduleRef && moduleRef.focus) {
              moduleRef.focus()
            }
            if (moduleRef && moduleRef.select) {
              moduleRef.select()
            }
            if (_this.info.type === 'uiSelect') {
              // 如果是下拉选择组件 则使下拉组件失去焦点 并隐藏选择框
              const selfModuleRef = _this.vuiComponents[_this.info._id] && _this.vuiComponents[_this.info._id].ref
              selfModuleRef.blur()
            }
          }
        })
    },
  },
}
